home *** CD-ROM | disk | FTP | other *** search
/ ...taking it to the Macs! / ...taking it to the Macs!.iso / Extras / Internet Developer Demos / Bare Bones Software Goodies / PopupFuncs 2.8.1 / xPop ƒ / comment.c next >
C/C++ Source or Header  |  1992-07-01  |  7KB  |  303 lines

  1. #include    <SetupA4.h>
  2. #include    "xpop.h"
  3.  
  4. enum    { kUnknown, kUncomment, kComment };
  5.  
  6. XPopRecPtr        gPopRec;
  7.  
  8. void    DoInit(void);
  9. void    DoClose(void);
  10. void    DoFOpen(void);
  11. void    DoFClose(void);
  12. void    DoQuery(void);
  13. void    DoIt(void);
  14.  
  15. Boolean    Comment( Handle txt, short language );
  16. Boolean Uncomment( Handle txt, short language );
  17. short        CountLines( Handle txt );
  18. void    PickComment( short language, short *commentSize, char **comment, char **endcomment );
  19. /*------------------------------------------------------------*/
  20. pascal void main( XPopRecPtr paramPtr)
  21.     {
  22.     RememberA0();
  23.     SetUpA4();
  24.     
  25.     gPopRec = paramPtr;
  26.     switch (paramPtr->message) {
  27.         case    xpop_init:    DoInit();        break;
  28.         case    xpop_close:    DoClose();        break;
  29.         case    xpop_fopen:    DoFOpen();        break;
  30.         case    xpop_fclose:    DoFClose();        break;
  31.         case    xpop_query:    DoQuery();        break;
  32.         case    xpop_doit:    DoIt();            break;
  33.         }
  34.     RestoreA4();
  35. }    /* main */
  36.  
  37. /*---------------*/
  38. void    DoInit(void)
  39. {
  40.     InitRecPtr        initStuff;
  41.     SelectionRecPtr    selection;
  42.     
  43.     selection = (SelectionRecPtr) gPopRec->param;
  44.  
  45.     initStuff = (InitRecPtr) NewPtr(sizeof(InitRec));
  46.     if ( initStuff!=NIL ) {
  47.         initStuff->version = 1;
  48.         initStuff-> language = (1 << _c) | (1 << _cplusplus) |
  49.                         (1 << _pascal) | (1 << _objectpascal) |
  50.                         (1 << _rez) | (1<<_asm);
  51.         initStuff-> writes = true;
  52.         initStuff-> sensitive = true;
  53.         initStuff-> getFileMsgs = false;
  54.         initStuff-> selStuff = kNeedSelection;
  55.         initStuff-> environment = (1 << kMPW) | (1<< kTHINK)| (1<< kGENERIC);        
  56.         }
  57.     gPopRec->result = (long) initStuff;
  58. }
  59. /*---------------*/
  60. void    DoClose(void)
  61. {}
  62. /*---------------*/
  63. void    DoFOpen(void)
  64. {}
  65. /*---------------*/
  66. void    DoFClose(void)
  67. {}
  68. /*---------------*/
  69. void    DoQuery(void)
  70. {
  71.     SelectionRecPtr    selection;
  72.     short        which;
  73.     
  74.     which = kUnknown;
  75.     gPopRec->result = (long) "\pComment(";
  76.     
  77.     selection = (SelectionRecPtr) gPopRec->param;
  78.     if ( selection->selEnd == selection->selStart ||
  79.          selection->hText == NIL )    /* can't comment if it ain't selected */
  80.         return;
  81.     
  82.     switch ( selection->language ) {
  83.         case    _c:
  84.         case    _cplusplus:
  85.         case    _rez:
  86.             if ( **selection->hText == '/' && *( (*selection->hText)+1)=='*' )
  87.                 which = kUncomment;
  88.             else
  89.                 which = kComment;
  90.             break;
  91.         case    _pascal:
  92.         case    _objectpascal:
  93.             if ( **selection->hText == '{' )
  94.                 which = kUncomment;
  95.             else
  96.                 which = kComment;
  97.             break;
  98.         case    _asm:
  99.             which = ( **selection->hText == ';' ) ?    kUncomment : kComment;
  100.             break;
  101.         }    /* switch */
  102.     switch ( which ) {
  103.         case    kUncomment:    gPopRec->result = (long) "\pUncomment"; break;
  104.         case    kComment:    gPopRec->result = (long) "\pComment"; break;
  105.         }
  106.     gPopRec->private = which;
  107. }
  108. /*---------------*/
  109. void    DoIt(void)
  110. {
  111.     SelectionRecPtr    selection;
  112.     PostDoRecPtr    rec;
  113.     Boolean            result;
  114.     
  115.     selection = (SelectionRecPtr) gPopRec->param;
  116.     rec = (PostDoRecPtr) NewPtr(sizeof(PostDoRec));
  117.     
  118.     if ( rec ) {
  119.                             /* gPopRec->private was set during the query message */
  120.         if ( gPopRec->private == kComment )
  121.             result = Comment( selection->hText, selection->language );
  122.         else
  123.             result = Uncomment( selection->hText, selection->language );
  124.         
  125.         rec->version = 1;
  126.         rec->paste = ( gPopRec->private != 0 && result );
  127.         rec->where = kReplace;
  128.         }
  129.     gPopRec->result = (long) rec;
  130. }
  131. /*---------------*/
  132. Boolean    Comment( Handle txt, short language );
  133. Boolean    Comment( Handle txt, short language )
  134. {
  135.     short    commentSize;
  136.     char    *comment, *endcomment, *pos, *newPos, *stop;
  137.     short        lineCount;
  138.     long    len;
  139.     Handle    newText;
  140.     
  141.     PickComment( language, &commentSize, &comment, &endcomment );
  142.     lineCount = CountLines( txt );
  143.     len = GetHandleSize( txt );
  144.     
  145. /*    For simplicity, I allocate another handle to put the commented text into.*/
  146. /*    People tight on memory who desire to comment a large block of text will not*/
  147. /*    be happy with this.*/
  148.  
  149.     newText = NewHandle( len + 2 * commentSize * (lineCount+1) + 128 );
  150.     if ( ! newText ) {
  151.         SysBeep(30);
  152.         goto failed;
  153.         }    
  154.     
  155.     pos = *txt;
  156.     stop = pos + len;
  157.     newPos = *newText;
  158.     
  159.     /* Comment the beginning */
  160.     BlockMove( comment, newPos, commentSize );
  161.     newPos += commentSize;
  162.  
  163.     /* Comment the middle */
  164.     while ( pos < stop ) {
  165.         while ( *pos!='\r' && pos < stop ) {
  166.             if ( (*pos == *endcomment) && (commentSize==1 || *(pos+1)==*(endcomment+1))) {
  167.                 *newPos++ = '»';
  168.                 pos += commentSize;
  169.                 }
  170.             else
  171.                 *newPos++ = *pos++;
  172.             }    /* copy and alter line */
  173.         
  174.         if ( pos < stop ) {
  175.             BlockMove( endcomment, newPos, commentSize);
  176.             newPos += commentSize;
  177.             *newPos++ = *pos++;
  178.             }
  179.         if ( pos < stop ) {
  180.             BlockMove( comment, newPos, commentSize);
  181.             newPos+= commentSize;    
  182.             }
  183.         }
  184.         
  185.     /* ... and now the end */
  186.     if ( *(newPos-1) != '\r' ) {
  187.         BlockMove( endcomment, newPos, commentSize);
  188.         newPos += commentSize;
  189.         }
  190.     
  191.     /* save the changes */
  192.     len = newPos - *newText;
  193.     HUnlock( txt );
  194.     SetHandleSize( txt, len );
  195.     HLock( txt );
  196.     BlockMove( *newText, *txt, len );
  197.     DisposHandle( newText );
  198.     return true;
  199. failed:
  200.     return false;
  201. }
  202.  
  203. /*---------------*/
  204. Boolean Uncomment( Handle txt, short language ) 
  205. {
  206.     short    commentSize;
  207.     char    *comment, *endcomment, *pos, *newPos, *stop;
  208.     short        lineCount;
  209.     long    len;
  210.     Handle    newText;
  211.     
  212.     PickComment( language, &commentSize, &comment, &endcomment );
  213.  
  214.     lineCount = CountLines( txt );
  215.     len = GetHandleSize( txt );
  216.     
  217.     newText = NewHandle( len );        /* more than needed */
  218.     if ( ! newText ) {
  219.         SysBeep(30);
  220.         goto failed;
  221.         }    
  222.     
  223.     pos = *txt;
  224.     stop = pos + len;
  225.     newPos = *newText;
  226.     
  227.     /* unComment the beginning */
  228.     pos += commentSize;
  229.  
  230.     /* unComment the middle */
  231.     while ( pos < stop ) {
  232.         while ( *pos!='\r' && pos < stop ) {
  233.             if ( *pos=='»' ) {
  234.                 BlockMove( endcomment, newPos, commentSize );
  235.                 newPos+= commentSize;
  236.                 pos++;
  237.                 }
  238.             else
  239.                 *newPos++ = *pos++;
  240.             }    /* copy and alter line */
  241.         
  242.         if ( pos < stop ) {
  243.         
  244.             /* erase the commentend at the end of line */
  245.             if ( (*(pos-commentSize) == *endcomment) && (commentSize==1 || *(pos-1)==*(endcomment+1))) {
  246.                 newPos -= commentSize;
  247.                 }
  248.                 
  249.             *newPos++ = *pos++;
  250.  
  251.             /* skip the comment at the beginning of line */
  252.             if ( (*pos == *comment) && (commentSize==1 || *(pos+1)==*(comment+1)) )
  253.                 pos += commentSize;
  254.             }
  255.         }
  256.         
  257.     /* ... and now the end */
  258.     if ( (*(pos-commentSize) == *endcomment) && (commentSize==1 || *(pos-1)==*(endcomment+1))) {
  259.         newPos -= commentSize;
  260.         }
  261.     
  262.     /* save the changes */
  263.     len = newPos - *newText;
  264.     SetHandleSize( txt, len );
  265.     BlockMove( *newText, *txt, len );
  266.     DisposHandle( newText );
  267.     return true;
  268. failed:
  269.     return false;
  270. }    /* Uncomment */
  271. /*---------------*/
  272. short        CountLines( Handle txt )
  273. {
  274.     register     char    *p,*stop;
  275.     short        cnt;
  276.     
  277.     stop = *txt + GetHandleSize(txt);
  278.     for ( p=*txt,cnt=0; p<stop; p++ )
  279.         if (*p=='\r')
  280.             cnt++;
  281.     
  282.     return cnt;
  283. }    /* CountLines() */
  284. /*----------------*/
  285. void    PickComment( short language, short *commentSize, char **comment, char **endcomment )
  286. {
  287.     if ( language==_c || language== _cplusplus || language== _rez ) {
  288.         *commentSize = 2;
  289.         *comment = "/*";
  290.         *endcomment = "*/";
  291.         }
  292.     else if ( language==_pascal || language== _objectpascal ) {
  293.         *commentSize = 1;
  294.         *comment = "{";
  295.         *endcomment = "}";
  296.         }
  297.     else if ( language==_asm ) {
  298.         *commentSize = 1;
  299.         *comment = ";";
  300.         *endcomment = " ";
  301.         }
  302. }    /* PickComment */
  303. /*----------------*/